package ${custom_package_manager};

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gomcarter.frameworks.base.common.AssertUtils;
import com.gomcarter.frameworks.base.pager.DefaultPager;
import ${custom_package_dto}.${custom_class_Dto};
import ${package.Entity}.${entity};
import ${custom_package_params}.${custom_class_CreateParam};
import ${custom_package_params}.${custom_class_QueryParam};
import ${custom_package_params}.${custom_class_UpdateParam};
import ${package.Service}.${table.serviceName};
import com.yifeng.repo.base.api.PageResult;
import com.yifeng.repo.base.params.IdParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.yifeng.repo.micro.service.server.helper.FesLambdaTransformer.*;

/**
 * <p>
 * ${table.comment!} 业务管理器
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Slf4j
@Service
public class ${custom_class_Manager} {
    /**
     * 【温馨提示】管理层代码规范
     * 1、Manager层负责组装业务逻辑，不要加事务。
     * 2、建议使用getter/setter拷贝数据对象，谨慎使用Bean拷贝。
     * 3、谨慎使用Lambda表达式操作数据库，避免查询所有字段，鼓励写SQL语句。
     */

    @Resource
    private ${table.serviceName} ${custom_service_instance_name};

    public ${custom_class_Dto} getById(${custom_idSimpleType} ${custom_idName}) {
        ${entity} entity = this.${custom_service_instance_name}.getById(${custom_idName});
        return copyProperties(entity, new ${custom_class_Dto}());
    }

    public List<${custom_class_Dto}> list(${custom_class_QueryParam} param, DefaultPager pager) {
        LambdaQueryWrapper<${entity}> lambdaWrapper = buildQueryWrapper(${entity}.class, param);
        Page<${entity}> pageParam = buildPageParam(pager, false);
        return this.${custom_service_instance_name}.list(pageParam, lambdaWrapper)
                .stream()
                .map(s -> copyProperties(s, new ${custom_class_Dto}()))
                .collect(Collectors.toList());
    }

    public List<${custom_class_Dto}> listByOffsetId(${custom_idSimpleType} ${custom_offsetIdName}, int batchSize) {
        LambdaQueryWrapper<${entity}> lambdaWrapper = buildQueryWrapper(${entity}::${custom_idGetMethod}, ${custom_offsetIdName});
        Page<${entity}> pageParam = buildPageParam(batchSize);
        return this.${custom_service_instance_name}.list(pageParam, lambdaWrapper)
                .stream()
                .map(s -> copyProperties(s, new ${custom_class_Dto}()))
                .collect(Collectors.toList());
    }

    public Long count(${custom_class_QueryParam} param) {
        LambdaQueryWrapper<${entity}> lambdaWrapper = buildCountWrapper(${entity}.class, param);
        return this.${custom_service_instance_name}.count(lambdaWrapper);
    }

    public Boolean contains(${custom_class_QueryParam} param) {
        LambdaQueryWrapper<${entity}> lambdaWrapper = buildContainsWrapper(${entity}.class, param, ${entity}::${custom_idGetMethod});
        Page<${entity}> pageParam = buildPageParam(1);
        return this.${custom_service_instance_name}.list(pageParam, lambdaWrapper).size() == 1;
    }

    public PageResult<${custom_class_Dto}> listPage(${custom_class_QueryParam} param, DefaultPager pager) {
        LambdaQueryWrapper<${entity}> lambdaWrapper = buildQueryWrapper(${entity}.class, param);
        Page<${entity}> pageParam = buildPageParam(pager, true);
        Page<${entity}> page = this.${custom_service_instance_name}.page(pageParam, lambdaWrapper);
        return copyPage(page, s -> copyProperties(s, new ${custom_class_Dto}()));
    }

    public ${custom_idSimpleType} create(${custom_class_CreateParam} param) {
        ${entity} entity = copyProperties(param, new ${entity}());
        this.${custom_service_instance_name}.save(entity);
        return entity.${custom_idGetMethod}();
    }

    public boolean update(${custom_class_UpdateParam} param) {
        ${entity} entity = this.${custom_service_instance_name}.getById(param.${custom_idGetMethod}());
        AssertUtils.notNull(entity);
        return this.${custom_service_instance_name}.updateById(copyProperties(param, entity));
    }

    public boolean delete(IdParam param) {
        return this.${custom_service_instance_name}.removeBatchByIds(param.getIds());
    }
}
